package qiyu.im.core.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import qiyu.im.core.server.constants.ImDecoder;
import qiyu.im.core.server.constants.ImEncoder;

import java.util.HashMap;

/**
 * Created with IntelliJ IDEA.
 * Description: im-core-server-Application 启动类
 * User: sfx
 * Date: 2023-10-16
 * Time: 17:11
 */
public class IMCoreServerApplication {

    //private final Logger logger = LoggerFactory.getLogger(IMCoreServerApplication.class);

    // 指定netty进程的端口
    private int port;

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    // 基于netty启动一个进程
    public void startApplication(int port) {
        // netty进程监听端口
        setPort(port);

        // 创建boosGroup,workerGroup
        NioEventLoopGroup boosGroup = new NioEventLoopGroup();
        NioEventLoopGroup workerGroup = new NioEventLoopGroup();
        // 创建bootStrap
        ServerBootstrap bootstrap = new ServerBootstrap();
        // 指定线程组
        bootstrap.group(boosGroup, workerGroup);
        // 指定channel
        bootstrap.channel(NioServerSocketChannel.class);

        // 初始化handler
        bootstrap.childHandler(new ChannelInitializer<Channel>() {
            @Override
            protected void initChannel(Channel ch) throws Exception {
                System.out.println("初始化连接通道....");
                // 设置具体IM传送的消息格式,会以ImMsg进行传输
                // 添加编解码器
                ch.pipeline().addLast(new ImDecoder());
                ch.pipeline().addLast(new ImEncoder());
                ch.pipeline().addLast(new ImCoreServerHandler());
            }
        });

        // 基于JVM钩子函数,实现netty进程优雅关闭
        Runtime runtime = Runtime.getRuntime();
        runtime.addShutdownHook(new Thread(() -> {
            boosGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }));

        try {
            // 阻塞主进程实现长期开启的效果
            ChannelFuture channelFuture = bootstrap.bind(port).sync();
            System.out.println("服务启动完成, 监听端口为 : " + getPort());
            channelFuture.sync().channel().closeFuture().sync();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) {
        IMCoreServerApplication application = new IMCoreServerApplication();
        application.startApplication(9090);
    }
}